/**
 * abyz - animated a..to..z char-selector
 *
 * @package abyz
 * @author Andrei Bakulin <andrei.bakulin@gmail.com>
 * @copyright 2009 Andrei Bakulin. All rights reserved.
 * @link http://abyz.web-dsl.com/
 * @version 0.1.0
 */

$(document).ready( function() {
    abyzGlobal = new abyzObject();
} );

function abyzObject()
{
    var objs = new Array();

    var grp_i = 0;

    $('table.abyz').each( function(i)
    {
        objs[grp_i] = new Array();

        var line_i = 0;

        $(this).attr('id','abyz_obj_'+grp_i);

        $('#abyz_obj_'+grp_i+' > tbody > tr').each( function(i)
        {
            objs[grp_i][line_i] = new Array();

            var cell_i = 0;

            $(this).attr( 'id', 'abyz_obj_'+grp_i+'_'+line_i );

            $('#abyz_obj_'+grp_i+'_'+line_i+' > td').each( function(i)
            {
                $(this).attr( 'id', 'abyz_obj_'+grp_i+'_'+line_i+'_'+cell_i );

                objs[grp_i][line_i][cell_i] = new abyzCellObject( $(this) );

                cell_i++;
            } );

            line_i++;
        } );

        grp_i++;
    } );

    this.objs = objs;
    this.timer = false;

    return true;
};

function get_css_attrs()
{
    return new Array( 'font-size', 'padding-left', 'padding-right' );
};

abyzObject.prototype.set_active = function( e_object )
{
    var active = e_object.attr('id').replace('abyz_obj_','').split('_');

    active[0] = parseInt( active[0] );
    active[1] = parseInt( active[1] );
    active[2] = parseInt( active[2] );

    var lp1, lp2, lp3;

    for( lp1=0; lp1<this.objs.length; lp1++ )
    {
        for( lp2=0; lp2<this.objs[lp1].length; lp2++ )
        {
            for( lp3=0; lp3<this.objs[lp1][lp2].length; lp3++ )
            {
                this.objs[lp1][lp2][lp3].need_scale_to = 0;
            }
        }
    }

    for( lp1=0; lp1<4; lp1++ )
    {
        lp3 = active[2]-lp1;

        if( lp3 >= 0 )
        {
            if( this.objs[ active[0] ][ active[1] ][ lp3 ].is_static )
            {
                break;
            }

            this.objs[ active[0] ][ active[1] ][ lp3 ].need_scale_to = Math.floor( ( 1 - 1/4 * lp1 ) * 100 );
        }
    }

    for( lp1=0; lp1<4; lp1++ )
    {
        lp3 = active[2]+lp1;

        if( lp3 < this.objs[ active[0] ][ active[1] ].length )
        {
            if( this.objs[ active[0] ][ active[1] ][ lp3 ].is_static )
            {
                break;
            }

            this.objs[ active[0] ][ active[1] ][ lp3 ].need_scale_to = Math.floor( ( 1 - 1/4 * lp1 ) * 100 );
        }
    }

    this.draw(0);

    return true;
};

abyzObject.prototype.unset_active = function()
{
    var lp1, lp2, lp3;

    for( lp1=0; lp1<this.objs.length; lp1++ )
    {
        for( lp2=0; lp2<this.objs[lp1].length; lp2++ )
        {
            for( lp3=0; lp3<this.objs[lp1][lp2].length; lp3++ )
            {
                this.objs[lp1][lp2][lp3].need_scale_to = 0;
            }
        }
    }

    this.draw(100);

    return true;
};

abyzObject.prototype.draw = function( delay )
{
    if( this.timer )
    {
        clearTimeout( this.timer );
        this.timer = false;
    }

    if( delay > 0 )
    {
        this.timer = setTimeout( 'abyzGlobal.draw(0)', delay );
        return true;
    }

    var lp1, lp2, lp3;
    var is_continue = false;

    for( lp1=0; lp1<this.objs.length; lp1++ )
    {
        for( lp2=0; lp2<this.objs[lp1].length; lp2++ )
        {
            for( lp3=0; lp3<this.objs[lp1][lp2].length; lp3++ )
            {
                is_continue = this.objs[lp1][lp2][lp3].draw() || is_continue;
            }
        }
    }

    if( is_continue )
    {
        this.timer = setTimeout( 'abyzGlobal.draw(0)', 20 );
    }

    return true;
};


function abyzCellObject( e_object )
{
    this.ref_object = e_object;

    this.is_static = e_object.hasClass('abyz_static');

    this.cur_scale = 0;
    this.need_scale_to = 0;

    this.obj_attrs = new Array();
    this.obj_attrs['min'] = new Array();
    this.obj_attrs['max'] = new Array();

    //-------------------------------------------------------------------------

    var lp, css_attrs = get_css_attrs();

    this.ref_object.addClass('abyz_cell_over');

    for( lp=0; lp<css_attrs.length; lp++ )
    {
        this.obj_attrs['max'][lp] = parseInt( this.ref_object.css( css_attrs[lp] ) );
    }

    this.ref_object.removeClass('abyz_cell_over');

    //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    this.ref_object.addClass('abyz_cell');

    for( lp=0; lp<css_attrs.length; lp++ )
    {
        this.obj_attrs['min'][lp] = parseInt( this.ref_object.css( css_attrs[lp] ) );
    }

    //-------------------------------------------------------------------------

    if( ! this.is_static )
    {
        this.ref_object.mouseover( function()
        {
            abyzGlobal.set_active( $(this) );
        } );

        this.ref_object.mouseout( function()
        {
            abyzGlobal.unset_active();
        } );
    }
};

abyzCellObject.prototype.draw = function()
{
    if( this.is_static )
    {
        return false;
    }

    if( this.cur_scale === this.need_scale_to )
    {
        return false;
    }

    //-------------------------------------------------------------------------

    var pre_scale = this.cur_scale;

    this.cur_scale += Math.floor( ( this.need_scale_to - this.cur_scale ) / ( this.need_scale_to > this.cur_scale ? 5 : 2.5 ) );

    if( pre_scale == this.cur_scale )
    {
        this.cur_scale = this.need_scale_to;
    }

    //-------------------------------------------------------------------------

    var cur_obj_attrs = new Array();
    var css_attrs = get_css_attrs();

    for( var lp=0; lp<css_attrs.length; lp++ )
    {
        cur_obj_attrs[lp] = Math.floor( this.obj_attrs['min'][lp] + ( this.obj_attrs['max'][lp] - this.obj_attrs['min'][lp] ) * this.cur_scale / 100 );
    }

    this.ref_object.css( {
        'font-size' :       cur_obj_attrs[0],
        'padding-left' :    cur_obj_attrs[1],
        'padding-right' :   cur_obj_attrs[2]
    } );

    return true;
};
